import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.*;

///////////////////////////////////////////////////////// DrawingArea
class Canvas extends JPanel {

	private static final long serialVersionUID = 1L;
	private static Canvas mCanvas = null;
	private Color mColor;      

	private BufferedImage mBuffImage = null; 

	private PLShape mShape = null;
	
	public enum CanvasIdT {
		kMin(-1), 
		kTraning(0), 
		kDrawing(1), 
		kMax(2);
		
		private int mId = 0;

		private CanvasIdT(int id) {setId(id);}
		
		public void setId(int id) {
			mId = id;
		}
		public int getId() {
			return mId;
		}
	}


	private Canvas() {
	    setPreferredSize(new Dimension(700,700));
	   // this.addMouseListener(this); 
	    // this.addMouseMotionListener(this); 

	}

	public static synchronized Canvas Obj() {
		if (mCanvas == null) {
			mCanvas = new Canvas();
		}
		return mCanvas;
	}

	// no cloning allowed
	public Object clone() throws CloneNotSupportedException {
		throw new CloneNotSupportedException();
	}	
	

	// returns the graphics object for the bufferImage
	public Graphics2D GetGraphics() {return mBuffImage.createGraphics();}


	//================================================ paintComponent
	@Override 
	public void paintComponent(Graphics g) {
		super.paintComponent(g);  // Ask parent to paint background.

		PLDebug.Info("Begin"); 

		this.setBackground(Color.WHITE);

		Graphics2D g2 = (Graphics2D)g;  // downcast to Graphics2D
		if (mBuffImage == null) {
			//--- This is the first time, initialize _bufImage
			PLDebug.Info("Creating buffered Image"); 
			int w = this.getWidth();
			int h = this.getHeight();
			mBuffImage = (BufferedImage)this.createImage(w, h);
			Graphics2D gc = mBuffImage.createGraphics();
	        gc.setStroke(new BasicStroke(5));
			gc.setColor(Color.white);
			gc.fillRect(0, 0, w, h); // fill in background
		}

		if (mBuffImage == null) {
			PLDebug.Err("mBuffImage equals null");        	        	
			return;	
		}

		g2.drawImage(mBuffImage, null, 0, 0);  // draw previous shapes
		PLDebug.Info("in paint components mBuffImage equals:" + mBuffImage); 

		if (mShape != null) {
			if (mColor != null)
				g2.setColor(mColor);
			
			mShape.Draw(g2);
		}
	}

	public void ClearCanvas() {
		mShape = null;
		mColor = null;
		
		Graphics2D buff = mBuffImage.createGraphics();
		if (buff == null){
			PLDebug.Err("buff is null, we have a problem!"); 
			return;
		}
		buff.setColor(Color.white);
		buff.fillRect(0, 0, getWidth(), getHeight()); 
		
		repaint();
	}
 
	public Dimension GetDimension() {return new Dimension(getWidth(), getHeight());}

	public void DrawShape(PLShape inShape, Color color, boolean temp) {
		repaint();
		if (temp) {
			mColor = color;
			mShape = inShape;			
		} else {
			Graphics2D g = GetGraphics();
			g.setColor(color);
			inShape.Draw(g);
			mShape = null;
			mColor = null;
		}
		
		repaint();
	}
   
}
